
// import * as d3 from "../lib/d3.js";
import * as d3 from "d3";
import {isDebugContext, isIOS} from "../util/context.js";
import {gaEvent} from "../util/ga.js";
import * as glTest from "../gl/glTest.js";
import * as twod from "../canvas/twod.js";
import {buildFastoverlay} from "../gl/fastoverlay.js";
import {$} from "../util/seq.js";


export function defineFastoverlay(
    fastoverlayAgent,
    globeAgent,
    activeLayerAgent,
    rendererAgent,
    overlay_type,
    hd_enabled,
    animation_enabled,
    interpolation_type,
    viewboxAgent,
) {
    const glReport = glTest.runTest(isDebugContext());
    const msg = glReport.pass ? "ok" : JSON.stringify(glReport);
    console.log(`test gl: ${msg}`);
    gaEvent("gl", msg);
    if (!glReport.pass) {
        return;
    }

    function isReady() {
        return overlay_type.get() !== "none" && rendererAgent.value();
    }
    function ƒlayer() {
        return activeLayerAgent.value();
    }
    function ƒalpha() {
        const layer = ƒlayer();
        const alpha = animation_enabled.get() ? layer?.alpha.animated : layer?.alpha.single;
        return (alpha ?? 0) / 255;
    }
    function ƒdisplay() {
        const {width, height} = viewboxAgent.value();
        return {width, height, pixelRatio: hd_enabled.get() ? 1.0 : 0.5};
    }
    function ƒprojection(glu) {
        return globeAgent.value()?.projection.optimize().webgl?.(glu);
    }
    function ƒgrid(glu) {
        return ƒlayer()?.grid?.().webgl?.(glu);
    }
    function ƒfield(glu) {
        return ƒlayer()?.field?.()[interpolation_type.get()]?.webgl?.(glu);
    }
    function ƒscale(glu) {
        return ƒlayer()?.scale.webgl?.(glu);
    }
    /**
     * Get the webgl components that are currently renderable.
     *
     * @param glu
     * @returns {Object[]} an array of webgl components, empty if any component does not support webgl.
     */
    function ƒcomponents(glu) {
        if (!isReady()) {
            return [];
        }
        const components = [
            ƒprojection(glu),
            ƒgrid(glu),
            ƒfield(glu),
            ƒscale(glu)
        ].filter(e => !!e);
        return components.length === 4 ? components : [];
    }

    const {width, height} = viewboxAgent.value();
    const canvas = d3.select("#fastoverlay")
        .style("width", `${width}px`)
        .style("height", `${height}px`)
        .node();
    const fastoverlay = buildFastoverlay(
        canvas,
        isIOS() ? twod.createCanvas() : undefined,
        ƒalpha,
        ƒdisplay,
        ƒcomponents,
    );

    // All of these events trigger a new frame.
    overlay_type.on($`change`, fastoverlay.draw);
    hd_enabled.on($`change`, fastoverlay.draw);
    animation_enabled.on($`change`, fastoverlay.draw);
    interpolation_type.on($`change`, fastoverlay.draw);
    // sharedConfig.on($`change:overlay_type`, fastoverlay.draw);
    // sessionConfig.on($`change:hd_enabled`, fastoverlay.draw);
    globeAgent.on($`update`, fastoverlay.draw);
    activeLayerAgent.on($`update`, fastoverlay.draw);
    rendererAgent.on($`redraw render update`, fastoverlay.draw);
    // animatorAgent.on($`update`, fastoverlay.draw);

    viewboxAgent.on($`update`, viewbox => {
        d3.select("#fastoverlay")
            .style("width", `${viewbox.width}px`)
            .style("height", `${viewbox.height}px`);
    });

    fastoverlayAgent.submit(fastoverlay);
}
